home *** CD-ROM | disk | FTP | other *** search
/ CD/PC Actual 3 / CD ACTUAL 3.iso / linux / incoming / libgr-2.000 / libgr-2 / libgr-2.0.3 / fbm / flrle.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-14  |  8.6 KB  |  347 lines

  1. /*****************************************************************
  2.  * flrle.c: FBM Release 1.0 25-Feb-90 Michael Mauldin
  3.  *
  4.  * flrle.c: Library routines for reading and Writing Utah RLE
  5.  *        raster toolkit format.
  6.  *
  7.  * CONTENTS
  8.  *    read_rle (image, rfile, mstr, mlen)
  9.  *    write_rle (image, wfile)
  10.  *
  11.  * EDITLOG
  12.  *    LastEditDate = Mon Jun 25 00:05:13 1990 - Michael Mauldin
  13.  *    LastFileName = /usr2/mlm/src/misc/fbm/flrle.c
  14.  *
  15.  * HISTORY
  16.  * 25-Jun-90  Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
  17.  *    Package for Release 1.0
  18.  *
  19.  * 13-Aug-89  Paul Milazzo (milazzo@diamond.bbn.com) BBN
  20.  *    Created.
  21.  *****************************************************************/
  22.  
  23. #include    <stdio.h>
  24. #include    "fbm.h"
  25.  
  26. #ifndef lint
  27. static char *fbmid =
  28. "$FBM flrle.c <1.0> 25-Jun-90  by Paul Milazzo, source code available \
  29. free from MLM@CS.CMU.EDU and from UUNET archives$";
  30. #endif
  31.  
  32. #ifdef RLE
  33.  
  34. /*#include    "svfb_global.h"*/
  35. #include    "rle.h"
  36.  
  37. #define        CMAP_COLORS        3
  38.  
  39. #define        TITLE_COMMENT        "TITLE"
  40. #define        CREDITS_COMMENT        "CREDITS"
  41. #define        ASPECT_COMMENT        "aspect_ratio"
  42. #define        CMAP_COMMENT        "color_map_length"
  43. #define        MAX_COMMENTS        4
  44. #define        MAX_LABEL_LENGTH    (sizeof (CMAP_COMMENT))
  45.  
  46. #define        TRUE            1
  47. #define        FALSE            0
  48.  
  49. static char    *CommentBuf (bpp)
  50. char        **bpp;
  51. {
  52.     char    *bp;
  53.  
  54.     if ((bp = (char *)malloc (FBM_MAX_TITLE + MAX_LABEL_LENGTH)) ==
  55.     (char *)NULL)
  56.     {
  57.     perror ("Can't allocate space for RLE comment");
  58.     exit (1);
  59.     }
  60.  
  61.     *bpp = bp;
  62.  
  63.     return bp;
  64. }
  65.  
  66. /****************************************************************
  67.  * write_rle (image, wfile)
  68.  ****************************************************************/
  69.  
  70. struct rle_hdr globals;
  71.  
  72. write_rle    (image, wfile)
  73. FBM        *image;
  74. FILE        *wfile;
  75. {
  76.     rle_pixel    **rowvec;
  77.     char    *comments[MAX_COMMENTS + 1];
  78.     char    **cp = comments;
  79.     rle_map    *colorMap = (rle_map *)NULL;
  80.     int        channel;
  81.     int        i;
  82.     int        j;
  83.     int        rows;
  84.     int        cols;
  85.     int        planes;
  86.     int        rowlen;
  87.     int        plnlen;
  88.  
  89.     if (image->hdr.physbits != 8) {
  90.     fputs ("write_rle:  error:  can only handle 8 physical bits per pixel\n",
  91.         stderr);
  92.     return (0);
  93.     }
  94.  
  95.     rows = image->hdr.rows;
  96.     cols = image->hdr.cols;
  97.     planes = image->hdr.planes;
  98.     rowlen = image->hdr.rowlen;
  99.     plnlen = image->hdr.plnlen;
  100.  
  101.     globals.ncolors    = planes;
  102.     globals.alpha        = 0;  /* no alpha channel */
  103.     globals.background    = 2;  /* clear background to bg_color */
  104.     globals.xmin        = 0;
  105.     globals.xmax        = cols - 1;
  106.     globals.ymin        = 0;
  107.     globals.ymax        = rows - 1;
  108.     globals.cmaplen    = 0;  /* log2(color_map_length) */
  109.     if (image->hdr.clrlen > 0) {
  110.     globals.ncmap = CMAP_COLORS;
  111.  
  112.     for (i = 1; i < image->hdr.clrlen / CMAP_COLORS; i <<= 1)
  113.         globals.cmaplen++;
  114.  
  115.     if ((colorMap = (rle_map *)malloc(image->hdr.clrlen*sizeof(rle_map))) ==
  116.         (rle_map *)NULL)
  117.     {
  118.         perror ("write_rle:  can't allocate RLE color map");
  119.         return 0;
  120.     }
  121.     for (i = 0; i < image->hdr.clrlen; i++)
  122.         colorMap[i] = (rle_map)image->cm[i] << 8;
  123.     globals.cmap    = colorMap;
  124.     }
  125.     else {
  126.     globals.ncmap    = 0;
  127.     globals.cmap    = (rle_map *)NULL;
  128.     }
  129.  
  130.     for (channel = 0; channel < planes; channel++)
  131.     RLE_SET_BIT (globals, channel);
  132.  
  133.     if (*image->hdr.title != '\0')
  134.     sprintf (CommentBuf (cp++), "%s=%s",
  135.              TITLE_COMMENT, image->hdr.title);
  136.  
  137.     if (*image->hdr.credits != '\0')
  138.     sprintf (CommentBuf (cp++), "%s=%s",
  139.              CREDITS_COMMENT, image->hdr.credits);
  140.  
  141.     if (image->hdr.aspect != 1.0)
  142.     sprintf (CommentBuf (cp++), "%s=%g",
  143.              ASPECT_COMMENT, image->hdr.aspect);
  144.  
  145.     /*
  146.      *  If the color map length is not a power of two, put the actual length
  147.      *  in a comment.
  148.      */
  149.     if (image->hdr.clrlen > 0 &&
  150.     (1 << globals.cmaplen) != image->hdr.clrlen / CMAP_COLORS)
  151.     {
  152.     sprintf (CommentBuf (cp++), "%s=%d",
  153.              CMAP_COMMENT, image->hdr.clrlen / CMAP_COLORS);
  154.     }
  155.  
  156.     *cp = (char *)NULL;
  157.  
  158.     globals.comments = cp > comments ? comments : (char **)NULL;
  159.  
  160.     globals.rle_file        = wfile;
  161.     globals.dispatch        = RUN_DISPATCH;
  162.   
  163.     rle_put_setup (&globals);
  164.  
  165.     if ((rowvec = (unsigned char **)malloc (planes*sizeof(unsigned char *))) ==
  166.     (unsigned char **)NULL)
  167.     {
  168.     perror ("write_rle:  can't allocate row indirection vectors");
  169.     return 0;
  170.     }
  171.  
  172.     for (j = rows - 1; j >= 0; --j) {
  173.     for (channel = 0; channel < planes; channel ++)
  174.         rowvec[channel] = image->bm + j * rowlen + channel * plnlen;
  175.     rle_putrow (rowvec, cols, &globals);
  176.     }
  177.     rle_puteof (&globals);
  178.  
  179.     free (rowvec);
  180.     while (cp > comments)
  181.     free (*--cp);
  182.     if (colorMap != (rle_map *)NULL)
  183.     free (colorMap);
  184.  
  185.     return 1;
  186. }
  187.  
  188. /****************************************************************
  189.  * read_rle (image, rfile)
  190.  ****************************************************************/
  191.  
  192. read_rle (image, rfile, mstr, mlen)
  193. FBM    *image;
  194. FILE    *rfile;
  195. char    *mstr;
  196. int    mlen;
  197. {
  198.     rle_pixel        **colorMap;
  199.     rle_pixel        **rowvec;
  200.     unsigned char    *cp;
  201.     char        *comment;
  202.     int            j;
  203.     int            channel;
  204.     int            rows;
  205.     int            planes;
  206.     int            rowlen;
  207.     int            plnlen;
  208.     int            mapEntries;
  209.     int            clearRow;
  210.  
  211.     /* must put the magic number back so the setup code can read it */
  212.     while (mlen--)
  213.     (void)ungetc (*mstr++, rfile);
  214.  
  215.     globals.rle_file = rfile;
  216.     switch (rle_get_setup (&globals)) {
  217.     case 0:
  218.         break;    /* success */
  219.     case -1:
  220.         fputs ("read_rle:  input is not a Utah RLE file.\n", stderr);
  221.         /* fall through... */
  222.     case -2:
  223.         return 0;    /* sv_get_setup already printed an error message */
  224.     case -3:
  225.         fputs ("read_rle:  input file is empty.\n", stderr);
  226.         return 0;
  227.     case -4:
  228.         fputs ("read_rle:  end-of-file encountered while reading RLE header.\n",
  229.            stderr);
  230.         return 0;
  231.     default:
  232.         fputs ("read_rle:  rle_get_setup returned something strange!\n",
  233.            stderr);
  234.     }
  235.  
  236.     if (globals.alpha) {
  237.     fputs ("read_rle:  discarding alpha channel.\n", stderr);
  238.     RLE_CLR_BIT (globals, RLE_ALPHA);
  239.     }
  240.  
  241.     image->hdr.cols    = globals.xmax - globals.xmin + 1;
  242.     image->hdr.rows    = rows = globals.ymax - globals.ymin + 1;
  243.     image->hdr.planes    = planes = globals.ncolors;
  244.     image->hdr.bits    = globals.cmaplen ? globals.cmaplen : 8;
  245.     image->hdr.physbits    = 8;
  246.     image->hdr.rowlen    = rowlen = image->hdr.cols;
  247.     image->hdr.plnlen    = plnlen = image->hdr.rows * image->hdr.rowlen;
  248.  
  249.     image->hdr.clrlen    = 1 << globals.cmaplen;
  250.     if ((comment = rle_getcom (CMAP_COMMENT, &globals)) != (char *)NULL)
  251.     image->hdr.clrlen = atoi (comment);
  252.     image->hdr.clrlen    *= globals.ncmap;
  253.  
  254.     if ((comment = rle_getcom (ASPECT_COMMENT, &globals)) != (char *)NULL)
  255.     image->hdr.aspect = atof (comment);
  256.     else
  257.     image->hdr.aspect = 1.0;
  258.  
  259.     if ((comment = rle_getcom (TITLE_COMMENT, &globals)) != (char *)NULL)
  260.     (void)strcpy (image->hdr.title, comment);
  261.     else
  262.     image->hdr.title[0] = '\0';
  263.     if ((comment = rle_getcom (CREDITS_COMMENT, &globals)) != (char *)NULL)
  264.     (void)strcpy (image->hdr.credits, comment);
  265.     else
  266.     image->hdr.credits[0] = '\0';
  267.  
  268.     image->cm = (unsigned char *)NULL;
  269.     image->bm = (unsigned char *)NULL;
  270.     alloc_fbm (image);
  271.  
  272.     if (image->hdr.clrlen > 0) {
  273.     mapEntries = (image->hdr.clrlen / globals.ncmap);
  274.     cp = image->cm;
  275.     colorMap = buildmap (&globals, CMAP_COLORS, 1.0);
  276.     for (channel = 0; channel < CMAP_COLORS; channel++) {
  277.         for (j = 0; j < mapEntries; j++)
  278.         *cp++ = colorMap[channel][j];
  279.         free (colorMap[channel]);
  280.     }
  281.     free (colorMap);
  282.     image->hdr.clrlen = mapEntries * CMAP_COLORS; /* renormalize clrlen */
  283.     }
  284.  
  285.     switch (globals.background) {
  286.     case 0:        /* no background color was saved */
  287.         clearRow = TRUE;    /* manually clear rows to 0 */
  288.         break;
  289.     case 1:        /* don't clear to the background color */
  290.         globals.background = 2;  /* force automatic clearing */
  291.         /* fall through... */
  292.     case 2:        /* clear to the background color */
  293.         clearRow = FALSE;
  294.         break;
  295.     default:
  296.         fprintf (stderr, "read_rle:  unknown background flag '%d'.\n",
  297.              globals.background);
  298.     }
  299.  
  300.     /* move image to origin */
  301.     globals.xmin    = 0;
  302.     globals.xmax    = image->hdr.cols - 1;
  303.     globals.ymin    = 0;
  304.     globals.ymax    = image->hdr.rows - 1;
  305.  
  306.     if ((rowvec = (unsigned char **)malloc (planes*sizeof(unsigned char *))) ==
  307.     (unsigned char **)NULL)
  308.     {
  309.     perror ("write_rle:  can't allocate row indirection vectors");
  310.     return 0;
  311.     }
  312.  
  313.     for (j = rows - 1; j >= 0; --j) {
  314.     for (channel = 0; channel < planes; channel ++) {
  315.         rowvec[channel] = image->bm + j * rowlen + channel * plnlen;
  316.         if (clearRow)
  317.         bzero ((char *)rowvec[channel], rowlen);
  318.     }
  319.     rle_getrow (&globals, rowvec);
  320.     }
  321.     free (rowvec);
  322.  
  323.     return 1;
  324. }
  325.  
  326. #else /* ! RLE */
  327.  
  328. /*ARGSUSED*/
  329. write_rle    (image, wfile)
  330. FBM        *image;
  331. FILE        *wfile;
  332. {
  333.     fputs ("RLE support was omitted at compile time.\n", stderr);
  334. }
  335.  
  336. /*ARGSUSED*/
  337. read_rle (image, rfile, mstr, mlen)
  338. FBM    *image;
  339. FILE    *rfile;
  340. char    *mstr;
  341. int    mlen;
  342. {
  343.     write_rle (image, rfile);
  344. }
  345.  
  346. #endif /* RLE */
  347.